package com.bjSoft.regressionTestTool.codeCoverage;

import java.io.File;
import java.util.HashMap;

import javax.xml.transform.stream.StreamSource;

import com.bjSoft.regressionTestTool.codeCoverage.base.ClassCoverageInfo;
import com.bjSoft.regressionTestTool.codeCoverage.base.MethodCoverage;

import net.sf.saxon.trans.XPathException;

import net.sf.saxon.Configuration;
import net.sf.saxon.om.NodeInfo;
import net.sf.saxon.om.SequenceIterator;
import net.sf.saxon.query.DynamicQueryContext;
import net.sf.saxon.query.StaticQueryContext;
import net.sf.saxon.query.XQueryExpression;


public class CoverageMatrixMaker {
	private HashMap<String, ClassCoverageInfo> coverageInfo;
	
	public CoverageMatrixMaker() {
		this.coverageInfo = new HashMap<String, ClassCoverageInfo>();
	}

	public HashMap<String, ClassCoverageInfo> getCoverageInfo() {
		return coverageInfo;
	}

	public void generateMatrixEntry(File xmlSource) throws XPathException {
		String testCaseName = xmlSource.getName().
									substring(0, xmlSource.getName().length() - 4);
		Configuration cfg = new Configuration();
		StaticQueryContext staticContext = new StaticQueryContext(cfg);
		DynamicQueryContext dynamicContext = new DynamicQueryContext(cfg);
		
		XQueryExpression expPackageName = 
			staticContext.compileQuery("//" + "package/@name");///@name"); 
		XQueryExpression expClassName = 
			staticContext.compileQuery("//" + "class/@name");///@name"); 
		XQueryExpression expMethodName = 
			staticContext.compileQuery("//" + "method/@name"); //@name
		XQueryExpression expCoverage = 
			staticContext.compileQuery("//" + "method/coverage/@value"); //@type e @value
		XQueryExpression expCoverageType = 
			staticContext.compileQuery("//" + "method/coverage/@type"); //@type e @value
		dynamicContext.setContextItem(cfg.buildDocument(
				new StreamSource(xmlSource)));
		
		SequenceIterator classNameIterator = expClassName.iterator(dynamicContext);		
		SequenceIterator methodNameIterator = expMethodName.iterator(dynamicContext);		
		SequenceIterator coverageValueIterator = expCoverage.iterator(dynamicContext);		
		SequenceIterator coverageTypeIterator = expCoverageType.iterator(dynamicContext);		
		SequenceIterator packageNameIterator = expPackageName.iterator(dynamicContext);
		
		NodeInfo packageNode = (NodeInfo) packageNameIterator.next();		
		NodeInfo classNode = (NodeInfo) classNameIterator.next();
		NodeInfo methodNode = (NodeInfo) methodNameIterator.next();		
		NodeInfo coverageNode = (NodeInfo) coverageValueIterator.next();		
		NodeInfo coverageTypeNode = (NodeInfo) coverageTypeIterator.next();
		
		while (packageNode != null) {
			String packageName = packageNode.getStringValue();
			System.out.println("package: " + packageName);
			while (classNode != null 
					&& classNode.getParent().getParent().getParent().isSameNodeInfo(packageNode.getParent())) {
				String className = classNode.getStringValue();
				System.out.println("\t class: " + className);
				ClassCoverageInfo classCovInfo;
				String classId = packageName + "." + className;
				if (!this.coverageInfo.containsKey(classId)) {
					classCovInfo = 
						new ClassCoverageInfo(className, packageName);
					this.coverageInfo.put(
							classId, classCovInfo);
				} else {
					classCovInfo = this.coverageInfo.get(classId);
				}
				//TODO: Ver a bronca de comparar esses valores.
				while (methodNode != null && methodNode.getParent().getParent().isSameNodeInfo(classNode.getParent())) {					
					String methodName = methodNode.getStringValue();	
					System.out.print("\t \t method: " + methodName);
					MethodCoverage methodCov = 
						classCovInfo.updateMethodCoverage(methodName);					
					if (coverageNode.getParent().equals(coverageTypeNode.getParent())) {
						String coverageValue = coverageNode.getStringValue();
						String typeNode = coverageTypeNode.getStringValue();
						String covP = coverageValue.substring(0, 2);
						System.out.println(" (coverage type: " + typeNode + " value : " + covP + ")");
						if (!covP.equalsIgnoreCase("0%") 
								&& typeNode.equalsIgnoreCase("method, %")) {
							methodCov.addTestCase(testCaseName);
						}
					}
					methodNode = (NodeInfo) methodNameIterator.next();
					for (int i = 0; i < 2; i ++) {
						coverageValueIterator.next();
						coverageTypeIterator.next();
					}
					coverageNode = (NodeInfo) coverageValueIterator.next();
					coverageTypeNode = (NodeInfo) coverageTypeIterator.next();					
				}
				classNode = (NodeInfo) classNameIterator.next(); 			
			}
			packageNode = (NodeInfo) packageNameIterator.next();		
		}		
	}
	//private void checkMethods()
}
